package finalfrontier;

import java.io.Serializable;

import java.util.Vector;
/**Classe AnimalElite
 * @author Nicolas Roy Boourdages
 */

public class AnimalElite extends CarreVieElite implements Serializable {
    
    
    private int lastFrame = 0;
    private float[] color = new float[3];
    
    private Vector<Coord> coordHerbivores;
    private Vector<Coord> coordVides;
    private Vector<Coord> coordHerbe;
    private Vector<Coord> coordCarnivores;
    private Vector<Coord> coordElite;
    private Vector<Coord> coordMutant;
    private int totalCase;
    private Coord cTemp = new Coord(0,0);
    
    private int lastCasei;
    private int lastCasej;
    private int steps = 1;
    private int lastFrameBouger = 0;
    
    private boolean cloned = false;
    private boolean veutBouger = true;
    
  public AnimalElite(double energy, double age, double death, String ori, long seed) {
      super(energy, age, death, ori, seed);
    
    coordHerbivores = new Vector<Coord>(Constants.VISION_RANGE_ELITE * Constants.VISION_RANGE_ELITE );
    coordCarnivores = new Vector<Coord>(Constants.VISION_RANGE_ELITE * Constants.VISION_RANGE_ELITE );
    coordVides = new Vector<Coord>(Constants.VISION_RANGE_ELITE * Constants.VISION_RANGE_ELITE );
    coordHerbe = new Vector<Coord>(Constants.VISION_RANGE_ELITE * Constants.VISION_RANGE_ELITE );
    coordElite = new Vector<Coord>(Constants.VISION_RANGE_ELITE * Constants.VISION_RANGE_ELITE );
    coordMutant = new Vector<Coord>(Constants.VISION_RANGE_ELITE * Constants.VISION_RANGE_ELITE );
  }
    
    public AnimalElite() {
        super();
        
    }

    public float[] execute(int i, int j) {
        if(lastFrame != DisplayWindow.frameCounter){
            
          if(lastFrame - lastFrameBouger > 60){
            if(!cloned){
              veutBouger = true;
              lastFrameBouger = lastFrame;
            }
            else{
              
              this.setEnergie(this.getEnergie() - 3.0);
              lastFrameBouger = lastFrame;
            }
            
          }
          else
          {
            veutBouger = false;
            
          }
          
          if(cloned){
            veutBouger = false;
            this.setEnergie(this.getEnergie() - 2.0);
          }
          
          if(veutBouger){
            buildMiniMap(i,j);
            
            deplacement(i,j);
          }
            vieillir();
            
            mourir(i,j);
        }
        lastFrame = DisplayWindow.frameCounter;
        
        return calculateColor();
    }

    private void buildMiniMap(int i, int j){
      
      coordHerbivores.clear();
      coordCarnivores.clear();
      coordElite.clear();
      coordMutant.clear();
      coordVides.clear();
      coordHerbe.clear();
      totalCase = 0;
      
      for (int q = -Constants.VISION_RANGE_ELITE; q <= Constants.VISION_RANGE_ELITE; q++){ 
          for (int w = -Constants.VISION_RANGE_ELITE; w <= Constants.VISION_RANGE_ELITE; w++){
              if ((i + q) >= 0 && (j + w) >= 0 && (i + q) < Constants.REAL_SIZE_X && (j + w) < Constants.REAL_SIZE_Y){
                  
                  cTemp = new Coord(i+q, j+w);
                  
                  if ( q == 0 && w == 0){
                      //do nothing-self
                  }
                  else if(!WorldMap.isEmpty(i + q, j + w)) {
                      
                      if (WorldMap.getMapVie(i + q, j + w).getClass() == AnimalHerbivore.class){
                          this.coordHerbivores.add(cTemp);
                      }
                      else if(WorldMap.getMapVie(i + q, j + w).getClass() == AnimalCarnivore.class){
                          this.coordCarnivores.add(cTemp);
                      }
                      else if(WorldMap.getMapVie(i + q, j + w).getClass() == AnimalMutant.class){
                          this.coordMutant.add(cTemp);
                      }
                      else if(WorldMap.getMapVie(i + q, j + w).getClass() == AnimalElite.class){
                          this.coordElite.add(cTemp);
                      }
                  }
                  else {
                      this.coordVides.add(cTemp);
                        if(WorldMap.getMapSol(i + q, j + w).getVegetation() > 0.0){
                          this.coordHerbe.add(cTemp);
                        }
                  
                  }
                  totalCase++;
              }
          }
          
      }
    }
    
  private void deplacement(int i, int j){
      if (veutBouger){
        
        if (getOrientation().equals("S")){
              if (j - steps >= 0 && j - steps < Constants.REAL_SIZE_Y && lastCasej != j - steps ){
                  if(WorldMap.isEmpty(i, j - steps)){
                      WorldMap.cloneVie(i, j - steps, i, j);
                      this.cloned = true;
                      lastCasej = j;
                      
                  
                  }
                  else{
                      setOrientation(getRandomDirection("S"));
                      
                  }
              }
              else{
                  setOrientation("N");
                  
              }
          }
         else if (getOrientation().equals("SW")){
              if (j - steps >= 0 && j - steps < Constants.REAL_SIZE_Y && lastCasej != j - steps && i - steps >= 0 && lastCasei != i && i - steps < Constants.REAL_SIZE_X){
                  if(WorldMap.isEmpty(i - steps, j - steps)){
                      WorldMap.cloneVie(i - steps, j - steps, i, j);
                    this.cloned = true;
                      lastCasej = j;
                      lastCasei = i;
                      
                  
                  }
                  else{
                      setOrientation(getRandomDirection("SW"));
                  }
              }
              else{
                  setOrientation("NE");
                  
              }
          }
          else if (getOrientation().equals("SE")){
                if (j - steps >= 0 && j - steps < Constants.REAL_SIZE_Y && lastCasej != j - steps && i + steps >= 0 && lastCasei != i && i + steps < Constants.REAL_SIZE_X){
                    if(WorldMap.isEmpty(i + steps, j - steps)){
                        WorldMap.cloneVie(i + steps, j - steps, i, j);
                      this.cloned = true;
                        lastCasej = j;
                        lastCasei = i;
                        
                    
                    }
                    else{
                        setOrientation(getRandomDirection("SE"));
                    }
                }
                else{
                    setOrientation("NW");
                    
                }
            }
            else if (getOrientation().equals("N")){
                if (j + steps < Constants.REAL_SIZE_Y && lastCasej != j + steps){
                    if(WorldMap.isEmpty(i, j + steps)){
                        WorldMap.cloneVie(i, j + steps, i, j);
                      this.cloned = true;
                        lastCasej = j;
                        
                    }
                    else{
                        setOrientation(getRandomDirection("N"));
                    }
                }
                else{
                    setOrientation("S");
                }
                
            }
            else if (getOrientation().equals("NE")){
                  if (j + steps >= 0 && j + steps < Constants.REAL_SIZE_Y && lastCasej != j + steps && i + steps >= 0 && i + steps < Constants.REAL_SIZE_X && lastCasei != i){
                      if(WorldMap.isEmpty(i + steps, j + steps)){
                          WorldMap.cloneVie(i + steps, j + steps, i, j);
                        this.cloned = true;
                          lastCasej = j;
                          lastCasei = i;
                          
                      
                      }
                      else{
                          setOrientation(getRandomDirection("NE"));
                      }
                  }
                  else{
                      setOrientation("SW");
                      
                  }
              }
            else if (getOrientation().equals("NW")){
                  if (j + steps >= 0 && j + steps < Constants.REAL_SIZE_Y && lastCasej != j + steps && i - steps >= 0 && i - steps < Constants.REAL_SIZE_X && lastCasei != i){
                      if(WorldMap.isEmpty(i - steps, j + steps)){
                          WorldMap.cloneVie(i - steps, j + steps, i, j);
                        this.cloned = true;
                          lastCasej = j;
                          lastCasei = i;
                          
                      
                      }
                      else{
                          setOrientation(getRandomDirection("NW"));
                      }
                  }
                  else{
                      setOrientation("SE");
                      
                  }
              }
              else if (getOrientation().equals("E")){
                      if (i + steps < Constants.REAL_SIZE_X && lastCasei != i + steps){
                          if(WorldMap.isEmpty(i + steps, j)){
                          WorldMap.cloneVie(i + steps, j, i, j);
                            this.cloned = true;
                          lastCasei = i;
                          
                          }
                          else{
                              setOrientation(getRandomDirection("E"));
                          }
                      }
                      else{
                          setOrientation("W");
                      }
                  }
              else if (getOrientation().equals("W")){
                  if (i - steps >= 0  && lastCasei != i - steps){
                      if(WorldMap.isEmpty(i - steps, j)){
                          WorldMap.cloneVie(i - steps, j, i, j);
                        this.cloned = true;
                          lastCasei = i;
                          
                      }
                      else{
                          setOrientation(getRandomDirection("W"));
                      }
                  }
                  else{
                      setOrientation("E");
                  }
              }
            else
            {
              setOrientation(getRandomDirection("W"));
            }
              
      }
  }

    private float[] calculateColor() {
        this.color[0] = 0.7f;
        this.color[1] = (float)(this.getEnergie() * 10) / 100;
        this.color[2] = 0.3f;
        
        return this.color;
    }

  public void setCloned(boolean cloned)
  {
    this.cloned = cloned;
  }

  public boolean isCloned()
  {
    return cloned;
  }
}
